package com.yswy.app.service.impl;

import com.alibaba.nacos.common.util.Md5Utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yswy.app.dto.TgCallBackIdReids;
import com.yswy.app.service.TgCallBackIdService;
import com.yswy.app.service.TgCallBackKsIdService;
import com.yswy.app.service.TgChannleService;
import com.yswy.common.utils.DateUtils;
import com.yswy.common.utils.TgKlUtil;
import com.yswy.common.utils.UserLockUtils;
import com.yswy.common.utils.redis.RedisConstants;
import com.yswy.common.utils.redis.RedisUtil;
import com.yswy.domain.common.BasePojo;
import com.yswy.domain.entity.*;
import com.yswy.domain.mapper.TgCallBackConfMapper;
import com.yswy.domain.mapper.TgChannleChildMapper;
import com.yswy.domain.mapper.TgChannleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class TgChannleServiceImpl extends ServiceImpl<TgChannleMapper, TgChannle>
        implements TgChannleService {
    @Autowired
    private TgChannleChildMapper tgChannleChildMapper;

    @Autowired
    private TgCallBackIdService tgCallBackIdService;
    @Autowired
    private TgCallBackKsIdService tgCallBackKsIdService;
    @Autowired
    private TgCallBackConfMapper tgCallBackConfMapper ;
    @Autowired
    private RedisUtil redisUtil ;
    static Map<String ,List<Integer>> integersTgChannle = new HashMap();
    static Map<String ,List<Integer>> integersTgChannleChild = new HashMap();
    static String spileCode = "-";
    @Override
    public Boolean isDeduction(String channle , Integer price) {
        synchronized (UserLockUtils.getLock("channleDeduction:"+channle)){
            //获取扣量缓存
            Integer deduction =  getIntegers(channle);
            if (deduction== null){

                List<TgChannleChild> tgChannleChildList = tgChannleChildMapper.getTgChannleChildByChannle(channle);
                if (tgChannleChildList.size()<= 0){
                    //没有配置子渠道，返回主渠道配置
                    return TgChannleIsDeduction(channle ,price);
                }else {
                    TgChannleChild tgChannleChild = tgChannleChildList.get(0);
                    if (tgChannleChild.getIsOpen() == 0){
                        log.info("渠道："+channle+"，未开启扣量");
                        return false;
                    }
                    if (price !=null){
                        if (tgChannleChild.getExaminePrice() > price){
                            log.info("渠道："+channle+"，考核价格不大于付费价格 不回传,考核价格："+tgChannleChild.getExaminePrice()+" 付款价格："+price);
                            return true;
                        }
                    }

                    List<TgChannleChildCode> tgChannleChildCodes = tgChannleChild.getTgChannleChildCodes();
                    if (tgChannleChildCodes == null || tgChannleChildCodes.size()<=0){
                        //没有配置子渠道参数，返回主渠道配置
                        return TgChannleIsDeduction(channle , price);
                    }else {
                        for (TgChannleChildCode t:
                                tgChannleChildCodes) {
                            if (DateUtils.belongCalendar(t.getStartTime() , t.getEndTime(),
                                    "HH:mm:ss")){
                                String channlenew = tgChannleChild.getChannle()+spileCode+t.getStartTime()+spileCode+t.getEndTime();
                                deduction = getIntegers( channlenew , t.getProportion() , 1);
                                break;
                            }
                        }
                    }
                }
            }

            if (deduction == null){
                log.info("渠道："+channle+"，没有配置扣量参数");
                return true ;
            }else {
                if (deduction ==0){
                    log.info("渠道："+channle+"，返回扣量");
                    return true ;
                }else {
                    log.info("渠道："+channle+"，返回不扣量");
                    return false ;
                }
            }
        }
    }

    @Override
    public TgCallBackConf getTgCallBackConf(String channle) {
        String[] channles = channle.split(spileCode);
        channle = channles[0] ;

        TgChannle tgChannle = null ;
        if (redisUtil.hasKey(RedisConstants.tgChannlecach+channle)){
            tgChannle = (TgChannle)redisUtil.getObejct(RedisConstants.tgChannlecach+channle);
        }else {
            tgChannle = getOne(new LambdaQueryWrapper<TgChannle>()
                    .eq(TgChannle::getChannle ,channle)
                    .eq(BasePojo::getIsDel , 0));
        }
        if (tgChannle!=null){
            TgCallBackConf tgCallBackConf =tgCallBackConfMapper.selectById(tgChannle.getCallBackConfId());
            redisUtil.setForObjectTimeCustom(RedisConstants.tgChannlecach+channle, tgChannle, 1, TimeUnit.DAYS);
            return tgCallBackConf;
        }else {
            return null ;
        }

    }
    /**
     * 获取用户来源
     * @param ip
     * @param type 0 登录  1 关键事件
     * @return  0 巨量引擎  1快手
     */
    @Override
    public Integer getUserSource(Long userId , String ip , Integer type) {
        String Modelip = ip ;
        String modelIpMd5 = Md5Utils.getMD5(Modelip.replaceAll("\\s" , "") , "utf8");
        log.info("Modelip："+modelIpMd5);
        String modelIpMd5RES=modelIpMd5;
        String ksmodelIpMd5RES=modelIpMd5;
        String hdmodelIpMd5RES=modelIpMd5;
        Integer re = -1 ;
        if (type == 0){
            modelIpMd5RES = RedisConstants.tgBackLoginLog+modelIpMd5;
            ksmodelIpMd5RES = RedisConstants.tgBackLoginLog_ks+modelIpMd5;
            hdmodelIpMd5RES = RedisConstants.tgBackLoginLog_Hd+modelIpMd5;
        }else if (type == 1){
            modelIpMd5RES = RedisConstants.tgBackPayLog+modelIpMd5;
            ksmodelIpMd5RES = RedisConstants.tgBackPayLog_ks+modelIpMd5;
            hdmodelIpMd5RES = RedisConstants.tgBackPayLog_Hd+modelIpMd5;
        }
        if (redisUtil.hasKey(modelIpMd5RES)){
            re = 0 ;
        }
        if (redisUtil.hasKey(ksmodelIpMd5RES)){
            re = 1 ;
        }
        if (redisUtil.hasKey(hdmodelIpMd5RES)){
            re = 2 ;
        }
        log.info("平台识别 用户ID ："+userId+"识别为："+re+"平台");
        return re;

    }

    @Override
    public void delDeduction(String channle , String star , String stop) {
        log.info("清楚扣量："+channle+spileCode+star+spileCode+stop);
        List<Integer> integers = integersTgChannle.get(channle);
        if (integers != null){
            log.info("清楚扣量："+channle+spileCode+star+spileCode+stop +"剩余数量："+integers.size());
        }
        integersTgChannle.remove(channle);
        integers = integersTgChannle.get(channle+spileCode+star+spileCode+stop);
        if (integers != null){
            log.info("清楚扣量："+channle+spileCode+star+spileCode+stop +"剩余数量："+integers.size());
        }
        integersTgChannleChild.remove(channle+spileCode+star+spileCode+stop);
    }


    public Boolean TgChannleIsDeduction(String channle , Integer price) {
        String[] channles = channle.split(spileCode);
        TgChannle tgChannle = getOne(new LambdaQueryWrapper<TgChannle>()
                .like(TgChannle::getChannle ,channles[0])
                .eq(BasePojo::getIsDel , 0));
        if (tgChannle==null)return null;
        if (price !=null){
            if (tgChannle.getExaminePrice() > price){
                log.info("渠道："+channles[0]+"，考核价格不大于付费价格 不回传,考核价格："+tgChannle.getExaminePrice()+" 付款价格："+price);
                return true;
            }
        }

        Integer integer = getIntegers( tgChannle.getChannle() , tgChannle.getProportion() , 0);
        return integer==0?true:false;
    }







    public static void main(String[] args) {
        System.out.println(DateUtils.belongCalendar( "2023-06-24 13:08:07", "2023-06-24 23:59:59",
                "yyyy-MM-dd HH:mm:ss"));
    }



    public static List<Integer> setIntegers(String channel , Integer proportion, Integer mapCode){
        List<Integer> list = TgKlUtil.getList(proportion);
        if (mapCode == 0){
            integersTgChannle.put(channel , list);
        }else {
            integersTgChannleChild.put(channel , list);
        }
        return list ;
    }



    public static Integer getIntegers( String channel , Integer proportion , Integer mapCode){
        Integer i = null;
        List<Integer> list = null;
        if (mapCode == 0){
            list = integersTgChannle.get(channel);
        }else {
            list = integersTgChannleChild.get(channel);
        }

        if (list == null || list.size() <= 0){
            list = setIntegers(channel , proportion ,mapCode);
        }
        i = list.get(0);
        list.remove(0);

        if (mapCode == 0){
            integersTgChannle.put(channel ,list );
        }else {
            integersTgChannleChild.put(channel ,list );
        }
        log.info("渠道："+channel+"缓存扣量剩余: "+list.size());
        return i ;
    }


    public static Integer getIntegers(String channel){
        List<Integer> value =null;
        //判断是否有匹配的扣量数组  先匹配子集扣量配置
        for (String key : integersTgChannleChild.keySet()) {
            String[] strings = key.split(spileCode);
            String mapChannle = strings[0];
            String str = strings[1];
            String end = strings[2];
            if (channel.equals(mapChannle)){
                if (DateUtils.belongCalendar(str , end,
                        "HH:mm:ss")){
                    value = integersTgChannleChild.get(key);
                    Integer i = value.get(0);
                    value.remove(0);
                    integersTgChannleChild.put(channel ,value );
                    return i ;
                }
            }
        }
        //在匹配父级扣量配置
        for (String key : integersTgChannle.keySet()) {
            String[] strings = key.split("-");
            String mapChannle = strings[0];
            if (channel.equals(mapChannle)){
                value = integersTgChannle.get(key);
                Integer i = value.get(0);
                value.remove(0);
                integersTgChannle.put(channel ,value );
                return i ;
            }
        }
        return null;
    }


}

